package com.example.service;

import com.example.elasticsearch.data.MyDocument;
import com.example.elasticsearch.repository.MyDocumentRepository;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class MyDocumentService {

    @Autowired
    private MyDocumentRepository repository;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    // 分页查询所有文档
    public Page<MyDocument> findAll(Pageable pageable) {
        return repository.findAll(pageable);
    }

    // 根据ID查询文档
    public Optional<MyDocument> findById(String id) {
        return repository.findById(id);
    }

    // 保存单个文档
    public MyDocument save(MyDocument document) {
        return repository.save(document);
    }

    // 批量保存文档
    public List<MyDocument> saveAll(List<MyDocument> documents) {
        return (List<MyDocument>) repository.saveAll(documents);
    }

    // 根据ID删除文档
    public void deleteById(String id) {
        repository.deleteById(id);
    }

    // 根据文本字段查询文档
    public List<MyDocument> findByTextField(String text) {
        return repository.findByTextField(text);
    }

    // 根据文本和关键字字段查询文档
    public List<MyDocument> findByTextFieldAndKeywordField(String text, String keyword) {
        return repository.findByTextFieldAndKeywordField(text, keyword);
    }

    // 根据整数和布尔字段查询文档
    public List<MyDocument> findByIntegerFieldAndBooleanField(Integer integerField, Boolean booleanField) {
        return repository.findByIntegerFieldAndBooleanField(integerField, booleanField);
    }

    // 根据日期字段范围查询文档
    public List<MyDocument> findByDateFieldBetween(LocalDate startDate, LocalDate endDate) {
        return repository.findByDateFieldBetween(startDate, endDate);
    }

    // 高亮显示关键字的查询
    public List<MyDocument> searchWithHighlight(String keyword) {
        // 构建高亮设置
        HighlightBuilder.Field highlightField = new HighlightBuilder.Field("textField")
                .preTags("<em>")
                .postTags("</em>");

        // 构建查询
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("textField", keyword))
                .withHighlightFields(highlightField)
                .build();

        // 执行查询
        SearchHits<MyDocument> searchHits = elasticsearchRestTemplate.search(searchQuery, MyDocument.class);

        // 处理高亮结果
        return searchHits.stream()
                .map(hit -> {
                    MyDocument doc = hit.getContent();
                    String highlightedText = String.join("", hit.getHighlightFields().get("textField"));
                    doc.setTextField(highlightedText);
                    return doc;
                })
                .collect(Collectors.toList());
    }

    // 聚合查询，统计 integerField 字段的值出现的次数
    public Map<Integer, Long> aggregateByIntegerField() {
        // 构建聚合查询
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchAllQuery())  // 匹配所有文档
                .withAggregations(AggregationBuilders.terms("integerFieldAgg").field("integerField")) // 使用 withAggregations()
                .build();

        // 执行查询
        SearchHits<MyDocument> searchHits = elasticsearchRestTemplate.search(searchQuery, MyDocument.class);

        // 获取聚合结果，并进行 null 检查和强制类型转换
        if (searchHits.getAggregations() != null && searchHits.getAggregations().aggregations() instanceof Aggregations) {
            Aggregations aggregations = (Aggregations) searchHits.getAggregations().aggregations();
            Terms terms = aggregations.get("integerFieldAgg");

            // 转换为 Map<Integer, Long>，键为 integerField 的值，值为出现次数
            return terms.getBuckets().stream()
                    .collect(Collectors.toMap(bucket -> bucket.getKeyAsNumber().intValue(), Terms.Bucket::getDocCount));
        }

        // 如果没有聚合结果，返回空的 Map
        return Collections.emptyMap();
    }
}
